using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Mail;
using System.Configuration;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace SendHTML
{
    class MailInfo
    {
        private string _server;

        public string SMTPServer
        {
            get { return _server; }
            set { _server = ( value == null) ? String.Empty : value.Trim(); }
        }

        private bool _authenticate;

        public bool SMTPAuthenticate
        {
            get { return _authenticate; }
            set { _authenticate = value; }
        }

        private string _user;

        public string SMTPUser
        {
            get { return _user; }
            set { _user = (value == null) ? String.Empty : value.Trim(); }
        }

        private string _password;

        public string SMTPPassword
        {
            get { return _password; }
            set { _password = value; }
        }

        private string _domain;

        public string SMTPDomain
        {
            get { return _domain; }
            set { _domain = value; }
        }

        private string _sender;

        public string Sender
        {
            get { return _sender; }
            set { _sender = (value == null) ? String.Empty : value.Trim(); }
        }

        private string _recipientsTO;

        public string RecipientsTO
        {
            get { return _recipientsTO; }
            set { _recipientsTO = (value == null) ? String.Empty : value.Trim(); }
        }

        private string _recipientsCC;

        public string RecipientsCC
        {
            get { return _recipientsCC; }
            set { _recipientsCC = (value == null) ? String.Empty : value.Trim(); }
        }

        private string _subject;

        public string Subject
        {
            get { return _subject; }
            set { _subject = value; }
        }

        private string _messageBody;

        public string Message
        {
            get { return _messageBody; }
            set { _messageBody = value; }
        }

        private string _filename;

        public string FileName
        {
            get { return _filename; }
            set { _filename = value; }
        }

        private bool IsEmailAddress(string address)
        {
            Regex r = new Regex(@"^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$", RegexOptions.IgnoreCase);
            return r.IsMatch(address);
        }

        private string ValidRecipientList(string addresslist, ref string[] reciplist)
        {
            if (addresslist == null)
                return "No recipients";

            reciplist = addresslist.Split(new char[2] { ',', ';' });
            foreach (string recip in reciplist)
            {
                if (!IsEmailAddress(recip.Trim()))
                    return "Invalid email address: " + recip;
            }
            return null;
        }

        public string CheckSender()
        {
            if (!IsEmailAddress(this.Sender))
                return "Invalid sender address: " + this.Sender;
            else
                return null;
        }

        public string CheckRecipients()
        {
            string errMsg;
            string[] recipients = null;
            bool bEmptyTO = true;
            bool bEmptyCC = true;

            if (this.RecipientsTO != null)
                if (this.RecipientsTO.Length > 0)
                {
                    errMsg = ValidRecipientList(this.RecipientsTO, ref recipients);
                    if (errMsg != null)
                        return errMsg;
                    else
                        bEmptyTO = false;
                }

            if (this.RecipientsCC != null)
                if (this.RecipientsCC.Length > 0)
                {
                    errMsg = ValidRecipientList(this.RecipientsCC, ref recipients);
                    if (errMsg != null)
                        return errMsg;
                    else
                        bEmptyCC = false;
                }

            if (bEmptyTO && bEmptyCC)
                return "Must provide at least one email address";
            else
                return null;

        }

        public string CheckFile()
        {
            // make sure file exists
            if (!System.IO.File.Exists(this.FileName))
                return "File does not exist";
            else
                return null;
        }

        public string CheckServer()
        {
            if (!(this.SMTPServer.Length > 0))
                return "Enter address of SMTP server";

            if (this.SMTPAuthenticate)
            {
                if (!(this.SMTPUser.Length > 0))
                    return "Enter user of SMTP server";
                // allow a blank password
            }
            return null;
        }

        public void Save()
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            System.Diagnostics.Debug.WriteLine(config.FilePath);

            // Add an entry to appSettings.
            config.AppSettings.Settings.Clear();
            config.AppSettings.Settings.Add("SMTPServer", this.SMTPServer);
            config.AppSettings.Settings.Add("SMTPUser", this.SMTPUser);
            //config.AppSettings.Settings.Add("SMTPPassword", this.SMTPPassword);
            config.AppSettings.Settings.Add("SMTPDomain", this.SMTPDomain);
            config.AppSettings.Settings.Add("SMTPAuth", this.SMTPAuthenticate.ToString());
            config.AppSettings.Settings.Add("HTMLFile", this.FileName);
            config.AppSettings.Settings.Add("Sender", this.Sender);
            config.AppSettings.Settings.Add("RecipTO", this.RecipientsTO);
            config.AppSettings.Settings.Add("RecipCC", this.RecipientsCC);
            config.AppSettings.Settings.Add("Subject", this.Subject);
            config.AppSettings.Settings.Add("MessageBody", this.Message);

            string newValue = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
            config.AppSettings.Settings.Add("LastSent", newValue);

            // Save the configuration file.
            config.Save(ConfigurationSaveMode.Full);

            // Force a reload of the changed section.
            //ConfigurationManager.RefreshSection("appSettings");
        }


        public void Load()
        {
            // Get the AppSettings collection.
            //Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            NameValueCollection appSettings = ConfigurationManager.AppSettings;

            if (appSettings != null)
            {
                this.SMTPServer = appSettings["SMTPServer"];
                this.SMTPUser = appSettings["SMTPUser"];
                this.SMTPPassword = appSettings["SMTPPassword"];
                this.SMTPDomain = appSettings["SMTPDomain"];
                this.SMTPAuthenticate = Convert.ToBoolean(appSettings["SMTPAuth"]);
                this.FileName = appSettings["HTMLFile"];
                this.Sender = appSettings["Sender"];
                this.RecipientsTO = appSettings["RecipTO"];
                this.RecipientsCC = appSettings["RecipCC"];
                this.Subject = appSettings["Subject"];
                this.Message = appSettings["MessageBody"];
            }
        }

        public void Send()
        {
            string[] recipients = null;
            string errMsg;

            //create the mail message
            MailMessage mail = new MailMessage();

            // FROM address
            mail.From = new MailAddress(this.Sender);

            // TO recipients
            if (this.RecipientsTO.Length > 0)
            {
                errMsg = ValidRecipientList(this.RecipientsTO, ref recipients);
                if (errMsg == null)
                {
                    foreach (string recip in recipients)
                    {
                        mail.To.Add(recip);
                        Debug.WriteLine(recip);
                    }
                }
            }

            // CC recipients
            if (this.RecipientsCC.Length > 0)
            {
                errMsg = ValidRecipientList(this.RecipientsCC, ref recipients);
                if (errMsg == null)
                {
                    foreach (string recip in recipients)
                    {
                        mail.CC.Add(recip);
                        Debug.WriteLine(recip);
                    }
                }
            }

            //set the content
            mail.Subject = this.Subject;

            //first we create the Plain Text part
            AlternateView plainView = AlternateView.CreateAlternateViewFromString(this.Message, null, "text/plain");

            //then we create the HTML part
            HtmlFile localFile = new HtmlFile(this.FileName);

            AlternateView htmlView = localFile.ConvertToMIME();
            //AlternateView htmlView = localFile.SimpleConvert();

            //add the parts to the mail message
            mail.AlternateViews.Add(plainView);
            mail.AlternateViews.Add(htmlView);

            Debug.WriteLine(mail.ToString());

            //send the message
            SmtpClient smtp = new SmtpClient(this.SMTPServer);
            if (this.SMTPAuthenticate)
            {
                if (this.SMTPDomain == null || this.SMTPDomain == String.Empty)
                    smtp.Credentials = new NetworkCredential(this.SMTPUser, this.SMTPPassword);
                else
                    smtp.Credentials = new NetworkCredential(this.SMTPUser, this.SMTPPassword, this.SMTPDomain);
            }
            smtp.Send(mail);
        }
    }
}
